package com.axxc.jpa.index.web;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder.Operator;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.axxc.jpa.index.doucument.ArticleIndex;
import com.axxc.jpa.index.filter.ArticleIndexFilter;
import com.axxc.jpa.index.repository.IArticleRepository;
import com.axxc.jpa.index.service.IArticleService;
import com.axxc.jpa.vo.ResponseVO;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * @ClassName: ArticleController
 * @Description: 操作文章索引类
 * @author 熊小川
 * @date 2018年5月23日 下午11:00:25
 * @See
 */
@RestController
@RequestMapping("index/article")
public class ArticleIndexController extends ElasticSearchBaseController {

	@Autowired
	@Qualifier("articleServiceIndex") // 本工程存在两个同类型接口,指定名称引入
	private IArticleService articleService;

	@Autowired
	@Qualifier("articleRepositoryIndex")
	private IArticleRepository articleRepository;

	@GetMapping("getTempLateInfo")
	public ResponseVO<ElasticsearchTemplate> getTempLateInfo() {
		return new ResponseVO<ElasticsearchTemplate>(elasticsearchTemplate);
	}

	@GetMapping("delete")
	@ApiOperation(value = "delete索引及映射", notes = "delete索引及映射")
	public ResponseVO<Boolean> delete() {
		return new ResponseVO<Boolean>(this.elasticsearchTemplate.deleteIndex(ArticleIndex.class));
	}

	@GetMapping("add")
	@ApiOperation(value = "创建索引及映射,并随机添加300篇文章", notes = "创建索引及映射,并随机添加300篇文章")
	public ResponseVO<String> add() {
		this.elasticsearchTemplate.createIndex(ArticleIndex.class);
		this.elasticsearchTemplate.putMapping(ArticleIndex.class);
		List<ArticleIndex> arrayList = new ArrayList<>();
		ArticleIndex article;
		for (int i = 0; i < 300; i++) {
			article = new ArticleIndex();
			article.setAuthor(i + "熊骑士");
			article.setContent(i + "今天基于springboot整合sping-data-elasticserach,学习ES搜索引擎技术及IK分词查询API语法,并简单测试其CRUD API");
			article.setCreateTime(simpleDateFormat.format(new Date()));
			article.setId(i);
			article.setTitle(i + "springboot整合sping-data-elasticserach");
			arrayList.add(article);
		}
		this.articleRepository.save(arrayList);
		return new ResponseVO<String>("添加成功");
	}

	@GetMapping("randomUpdate")
	@ApiOperation(value = "随机修改文章", notes = "随机修改文章")
	public ResponseVO<String> update() {
		Random random = new Random();
		List<ArticleIndex> arrayList = new ArrayList<>();
		for (int i = 0; i < 30; i++) {
			int randomId = random.nextInt(300) + 1;
			System.out.println(randomId);
			ArticleIndex article = new ArticleIndex();
			article.setId(randomId);
			article.setAuthor("大灰狼");
			article.setContent(
					"定义的拦截器,需要注册到拦截器链中 注册拦截器 ,在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作");
			article.setCreateTime(simpleDateFormat.format(new Date()));
			article.setTitle("web 拦截器");
			arrayList.add(article);
		}
		this.articleRepository.save(arrayList);
		return new ResponseVO<String>("添加成功");
	}

	@GetMapping("/search")
	@ApiOperation(value = "搜索文章", notes = "搜索文章")
	@ApiImplicitParams(value = { @ApiImplicitParam(name = "page", value = "当前页,此参数从0开始", paramType = "query"),
			@ApiImplicitParam(name = "size", value = "每页显示数量,此参数默认20", paramType = "query") })
	public ResponseVO<Object> search(@ModelAttribute ArticleIndexFilter filter, String page, String size) {
		logger.info("入参:{}", JSONObject.toJSON(filter));
		ResponseVO<Object> responseVO = new ResponseVO<>("添加成功");
		page = StringUtils.isBlank(page) == true || Integer.valueOf(page) < 0 ? "0" : page;
		size = StringUtils.isBlank(size) == true || Integer.valueOf(size) < 0 ? "20" : size;
		Pageable pageable = new PageRequest(Integer.valueOf(page), Integer.valueOf(size));
		if (StringUtils.isBlank(String.valueOf(filter.getId())) && StringUtils.isBlank(filter.getTitle())
				&& StringUtils.isBlank(filter.getContent()) && StringUtils.isBlank(filter.getAuthor())) {
			Page<ArticleIndex> pageData = this.articleRepository.findAll(pageable);
			responseVO.setTotal(pageData.getTotalElements());
			responseVO.setContent(pageData.getContent());
		} else {
			// Criteria criteria = new Criteria();
			BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
			if (filter.getId() != null && filter.getId() >= 0) {
				TermQueryBuilder termQueryBuilder = new TermQueryBuilder("id", filter.getId());
				boolQueryBuilder.must(termQueryBuilder);
			}
			if (StringUtils.isNotBlank(filter.getAuthor())) {
				WildcardQueryBuilder termQueryBuilder = new WildcardQueryBuilder("author",
						"*" + filter.getAuthor() + "*");
				boolQueryBuilder.must(termQueryBuilder);
			}
			if (StringUtils.isNotBlank(filter.getTitle())) {
				// 单词条模糊匹配查询
				WildcardQueryBuilder termQB = new WildcardQueryBuilder("title", "*" + filter.getTitle() + "*");
				// No.2多词条时分词匹配 AND
				QueryStringQueryBuilder stringQueryBuilder = new QueryStringQueryBuilder(filter.getTitle())
						.field("title").defaultOperator(Operator.AND);
				// 两种情况 OR
				BoolQueryBuilder tempBoolQueryBuilder = new BoolQueryBuilder();
				tempBoolQueryBuilder.should(termQB);
				tempBoolQueryBuilder.should(stringQueryBuilder);
				boolQueryBuilder.must(tempBoolQueryBuilder);
			}
			if (StringUtils.isNotBlank(filter.getContent())) {
				// No.1 单词条匹配
				WildcardQueryBuilder termQueryBuilder = new WildcardQueryBuilder("content",
						"*" + filter.getContent() + "*");
				// No.2多词条时分词匹配 AND
				QueryStringQueryBuilder stringQueryBuilder = new QueryStringQueryBuilder(filter.getContent())
						.field("content").defaultOperator(Operator.AND);
				// 两种情况 OR
				BoolQueryBuilder tempBoolQueryBuilder = new BoolQueryBuilder();
				tempBoolQueryBuilder.should(termQueryBuilder);
				tempBoolQueryBuilder.should(stringQueryBuilder);
				boolQueryBuilder.must(tempBoolQueryBuilder);
			}
			logger.info("查询条件:{}", JSONObject.toJSON(boolQueryBuilder));
			SearchQuery searchQuery = new NativeSearchQuery(boolQueryBuilder);
			searchQuery.setPageable(pageable);
			Page<ArticleIndex> pageData = this.articleRepository.search(searchQuery);
			responseVO.setTotal(pageData.getTotalElements());
			responseVO.setContent(pageData.getContent());
		}
		return responseVO;
	}

}
